/**
 * Copyright (C) 2013 SHANGHAI VOLKSWAGEN, All rights reserved.
 * License version 1.0, a copy of which has been included with this.
 *
 * @File name：com.market.test.server.service.impl.ExcelServiceImpl
 * @Create on：2024/3/11
 * @Author：liuchang
 */
package com.market.test.server.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.github.pagehelper.Page;
import com.market.test.common.domain.ExcelData;
import com.market.test.server.listener.SalariesListener;
import com.market.test.server.mapper.ExcelMapper;
import com.market.test.server.service.ExcelService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/**
 * <p>ClassName：ExcelServiceImpl</p >
 * <p>Description：</p >
 * <p>Author：liuchang</p >
 * <p>Date：2024/3/11</p >
 */
@Service
@Log4j2
public class ExcelServiceImpl implements ExcelService {
    @Autowired
    private ExcelMapper excelMapper;
    @Autowired
    private SalariesListener salariesListener;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    private ExecutorService executorService = Executors.newFixedThreadPool(20);


    @Override
    public void easyImport(MultipartFile file) throws IOException {

        ArrayList<Callable<Object>> tasks = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            int num=i;
            tasks.add(() -> {
                EasyExcel.read(file.getInputStream(), ExcelData.class,salariesListener).sheet(num).doRead();
                return null;
        });
        }
        try {
            executorService.invokeAll(tasks);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public Integer selectAll() {
        Integer count=excelMapper.selectAll();
        return count;
    }

    @Override
    public void easyExport(HttpServletResponse response) throws IOException {

        ServletOutputStream outputStream = response.getOutputStream();
        long start = System.currentTimeMillis();
        System.out.println("-----任务开始执行--------");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String("测试数据.xlsx".getBytes("UTF-8"), "ISO8859-1"));


        //查询总条数
        Integer count = excelMapper.selectAll();
        int pageSize=10000;
        //创建一个EasyExcel的ExcelWriter对象，并将其配置为将Excel数据写入到给定的outputStream中
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
        //创建complebleFuture集合
        List<CompletableFuture> completableFutures=new ArrayList<>();
        for (int i = 0; i < (count / pageSize) + 1; i++) {
            int finalI=i;
            CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
                //分页查找表里面的数据
                List<ExcelData> list=excelMapper.findLimit(finalI * pageSize, pageSize);
                if (!CollectionUtils.isEmpty(list)) {
                    WriteSheet writeSheet = EasyExcel.
                            writerSheet(finalI, "模板" + finalI).
                            head(ExcelData.class).
                            registerWriteHandler(
                                    new LongestMatchColumnWidthStyleStrategy()
                            ).build();
                    //加锁 同步线程访问共享变量会有
                    synchronized (excelWriter){
                        excelWriter.write(list,writeSheet);
                    }
                }

            },threadPoolExecutor);
            completableFutures.add(voidCompletableFuture);
        }

        //遍历completableFutures
        for (CompletableFuture completableFuture : completableFutures) {
            completableFuture.join();
        }
        //刷新流
        excelWriter.finish();
        System.out.println("消耗的时间为"+(System.currentTimeMillis() - start)/1000+"秒");

        outputStream.flush();

        response.getOutputStream().close();


    }
}
